package com.neuronbit.businessflow.intellij.actions;

import com.neuronbit.businessflow.intellij.BpmBundle;
import com.neuronbit.businessflow.intellij.BpmFileType;
import com.neuronbit.businessflow.intellij.BpmPsiBundle;
import com.neuronbit.businessflow.intellij.lang.PsiBpmFile;
import com.intellij.codeInsight.daemon.JavaErrorBundle;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightClassUtil;
import com.intellij.core.JavaPsiBundle;
import com.intellij.ide.actions.CreateFileFromTemplateDialog;
import com.intellij.ide.actions.JavaCreateTemplateInPackageAction;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.fileTemplates.actions.CreateFromTemplateActionBase;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.InputValidatorEx;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiUtil;
import com.intellij.ui.IconManager;
import com.intellij.ui.PlatformIcons;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Properties;

/**
 * The type Create flow action.
 */
public class CreateFlowAction extends JavaCreateTemplateInPackageAction<PsiBpmFile> {
    /**
     * Instantiates a new Create flow action.
     */
    public CreateFlowAction() {
        super("", BpmBundle.message("action.create.new.flow.description", new Object[0]), IconManager.getInstance().getPlatformIcon(PlatformIcons.Class), true);
    }

    @Override
    protected void buildDialog(@NotNull Project project, @NotNull PsiDirectory directory, @NotNull CreateFileFromTemplateDialog.Builder builder) {
        builder
                .setTitle(BpmBundle.message("action.create.new.flow"))
                .addKind(BpmPsiBundle.message("node.flow.tooltip"), IconManager.getInstance().getPlatformIcon(com.intellij.ui.PlatformIcons.Class), "Flow");

        LanguageLevel level = PsiUtil.getLanguageLevel(directory);

        builder.setValidator(new InputValidatorEx() {
            @Override
            public String getErrorText(String inputString) {
                if (inputString.length() > 0 && !PsiNameHelper.getInstance(project).isQualifiedName(inputString)) {
                    return JavaErrorBundle.message("create.class.action.this.not.valid.java.qualified.name");
                }
                String shortName = StringUtil.getShortName(inputString);
                if (HighlightClassUtil.isRestrictedIdentifier(shortName, level)) {
                    return JavaErrorBundle.message("restricted.identifier", shortName);
                }
                return null;
            }

            @Override
            public boolean checkInput(String inputString) {
                return true;
            }

            @Override
            public boolean canClose(String inputString) {
                return !StringUtil.isEmptyOrSpaces(inputString) && getErrorText(inputString) == null;
            }
        });
    }

    @Override
    protected @NlsContexts.Command String getActionName(PsiDirectory directory, @NotNull String newName, String templateName) {
        PsiPackage psiPackage = JavaDirectoryService.getInstance().getPackage(directory);
        return BpmBundle.message("progress.creating.flow", StringUtil.getQualifiedName(psiPackage == null ? "" : psiPackage.getQualifiedName(), newName));

    }

    @Override
    protected @Nullable PsiElement getNavigationElement(@NotNull PsiBpmFile createdElement) {
//        if (createdElement.isRecord()) {
//            PsiRecordHeader header = createdElement.getRecordHeader();
//            if (header != null) {
//                return header.getLastChild();
//            }
//        }
//        return createdElement.getLBrace();

        return createdElement;
    }

    @Override
    protected @Nullable PsiBpmFile doCreate(final PsiDirectory dir, final String className, String templateName) throws IncorrectOperationException {
        PsiClass psiClass = JavaDirectoryService.getInstance().createClass(dir, className, "FlowClass", true);
        if (psiClass == null) {
            return null;
        }

        Project project = dir.getProject();
        FileTemplate template = FileTemplateManager.getInstance(project).getInternalTemplate(templateName);

        Properties defaultProperties = FileTemplateManager.getInstance(project).getDefaultProperties();
        Properties properties = new Properties(defaultProperties);
        properties.setProperty(FileTemplate.ATTRIBUTE_NAME, className);

        String ext = BpmFileType.INSTANCE.getDefaultExtension();
        String fileName = className + "." + ext;

        PsiElement element;
        try {
            element = FileTemplateUtil.createFromTemplate(template, fileName, properties, dir);
        } catch (IncorrectOperationException | ProcessCanceledException e) {
            throw e;
        } catch (Exception e) {
            LOG.error(e);
            return null;
        }

        final PsiBpmFile file = (PsiBpmFile) element.getContainingFile();

        if (template.isLiveTemplateEnabled()) {
            Document document = file.getViewProvider().getDocument();
            if (document != null) {
                PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
                CreateFromTemplateActionBase.startLiveTemplate(file);
            }
        }
        return file;
    }

}
